package cn.itcast.web.controller;

import cn.itcast.service.system.UserService;
import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.ModuleService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
public class LoginController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private ModuleService moduleService;

    @RequestMapping("/login")
    public String login(String email, String password) {
        //1. 判断邮箱与密码是否为空，如果两者有一位空都需要返回login.jsp 提示用户
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password)) {
            //把数据存储到域中，如果要从域中取出数据，我们需要使用使用请求转发。
            request.setAttribute("error", "用户名或者密码不能为空");
            return "forward:/login.jsp"; // 是会经过视图解析器的。
        }
        try {
            // 1.获取subject对象
            Subject subject = SecurityUtils.getSubject();

            //2. 把用户输入的邮箱与密码封装成一个Token
            UsernamePasswordToken token = new UsernamePasswordToken(email, password);
            // 3.使用subject发出登录的请求，并且把token传递给Realm
            subject.login(token);
            //4.通过shiro获取用户对象，保存到session中（如果登陆成功，你可以得到一个登陆者用户对象）
            User loginUser = (User) subject.getPrincipal(); // 获取安全数据（用户对象）

            //其实shiro登陆成功后，shiro也会在session中做很多的登录成功的标记，这个过程不需要你们参与
            //5. 获取菜单数据（登陆成功后你要完成事情）
            //这里保存User对象到session中，这里不是做登陆成功的标记，因为登陆成功的标记shiro自己去完成了， 我们这里存储只是为了页面上数据显示
            session.setAttribute("loginUser", loginUser);
            List<Module> moduleList = moduleService.findModuleByUser(loginUser);

            //菜单大家觉得放在哪个域比较好呢？ request  ， session域
            //由于菜单需要被多次点击，每点击一次就会出现一个request对象，所以放入到request域中不合适
            session.setAttribute("modules", moduleList);

            //登录成功跳转页面
            return "home/main";

        } catch (UnknownAccountException e) {
            //如果收到该异常就是代表邮箱错误
            request.setAttribute("error","该邮箱不存在！");
            return "forward:/login.jsp";

        } catch (IncorrectCredentialsException e) {
            //如果收到该异常就是代表密码错误
            request.setAttribute("error", "用户名或者密码错误！");
            return "forward:/login.jsp";
        }
    }

    /**
     * 该方法的作用： 注销
     * url: /logout.do
     * 参数：无
     * 返回：重新返回登陆页面
     * @return
     */
    @RequestMapping("logout")
    public String logout() {
        //你需要把shiro里面登录标识删除
        Subject subject = SecurityUtils.getSubject();
        subject.logout(); // 这个方法会shiro登录成功标记全部删除
        session.removeAttribute("loginUser");

        //由于这里没有往域中存储数据，所以你可以使用请求转发也可以使用请求重定向
        return "redirect:/login.jsp";
    }

    /**
     * 作用：返回后台主页正文部分默认加载的页面home.jsp
     * @return
     */
    @RequestMapping("/home")
    public String home() {
        return "home/home";
    }
}